﻿using System;
using System.Globalization;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Web.Mvc;
using System.Web.Mvc.Html;

namespace Fuse8.ContentManagementFramework.Web.Extensions
{
    public static class HtmlHelperExtensions
    {
        /// <summary>
        /// Generates radion button with id having specified suffix. This could be used to generate radio groups
        /// </summary>
        /// <typeparam name="TModel">The type of the model.</typeparam>
        /// <typeparam name="TValue">The type of the model property.</typeparam>
        /// <param name="helper">This HTML Helper instance</param>
        /// <param name="expression">Expression most often denotes model property.</param>
        /// <param name="value">The input field value.</param>
        /// <param name="idSuffix">The id suffix.</param>
        /// <returns>Generated radio button.</returns>
        public static MvcHtmlString RadioButtonWithIdSuffix<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, object value, string idSuffix)
        {
            return helper.RadioButton(helper.GetClientName(expression), value, value.Equals(expression.Compile().Invoke(helper.ViewData.Model)), new Dictionary<string, object> { { "id", helper.GetClientIdWithSuffix(expression, idSuffix) } });
        }

        /// <summary>
        /// Generates radion button with id having specified suffix. This could be used to generate radio groups
        /// </summary>
        /// <typeparam name="TModel">The type of the model.</typeparam>
        /// <typeparam name="TValue">The type of the model property.</typeparam>
        /// <param name="helper">This HTML Helper instance</param>
        /// <param name="expression">Expression most often denotes model property.</param>
        /// <param name="value">The input field value.</param>
        /// <param name="idSuffix">The id suffix.</param>
        /// <param name="htmlAttributes">Html attributes.</param>
        /// <returns>Generated radio button.</returns>
        public static MvcHtmlString RadioButtonWithIdSuffix<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, object value, string idSuffix, IDictionary<string, object> htmlAttributes)
        {
            htmlAttributes.Add("id", helper.GetClientIdWithSuffix(expression, idSuffix));

            return helper.RadioButton(helper.GetClientName(expression), value, value.Equals(expression.Compile().Invoke(helper.ViewData.Model)), htmlAttributes);
        }

        /// <summary>
        /// Get full client name for given model expression.
        /// </summary>
        /// <typeparam name="TModel">The type of the model.</typeparam>
        /// <typeparam name="TValue">The type of the model property.</typeparam>
        /// <param name="helper">This HTML Helper instance</param>
        /// <param name="expression">Expression most often denotes model property.</param>
        /// <returns>Full client name.</returns>
        public static string GetClientFullName<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression)
        {
            return helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(ExpressionHelper.GetExpressionText(expression));
        }

        /// <summary>
        /// Get expression name without root path.
        /// </summary>
        /// <typeparam name="TModel">The type of the model.</typeparam>
        /// <typeparam name="TValue">The type of the model property.</typeparam>
        /// <param name="helper">This HTML Helper instance</param>
        /// <param name="expression">Expression most often denotes model property.</param>
        /// <returns>Client name.</returns>
        public static string GetClientName<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression)
        {
            return ExpressionHelper.GetExpressionText(expression);
        }

        /// <summary>
        /// Get client id for given model expression.
        /// </summary>
        /// <typeparam name="TModel">The type of the model.</typeparam>
        /// <typeparam name="TValue">The type of the model property.</typeparam>
        /// <param name="helper">This HTML Helper instance</param>
        /// <param name="expression">Expression denoting model property.</param>
        /// <param name="idSuffix">The id suffix.</param>	    
        /// <returns>Client id.</returns>
        public static string GetClientIdWithSuffix<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, string idSuffix)
        {
            return helper.GetClientFullName(expression).Replace('.', '_') + "_" + idSuffix;
        }

        public static MvcHtmlString GetClientIdFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
        {
            string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
            string inputFieldId = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName);
            return MvcHtmlString.Create(inputFieldId);
        }

        /// <summary>
        /// Builds element name for administration view control.
        /// </summary>
        /// <param name="helper">HTML Helper</param>
        /// <param name="pageControlId">Page control Id</param>
        /// <param name="elementName">Element (property name). If not specified then 'model' is used.</param>
        /// <returns></returns>
        /// <remarks>Do not pass elementName for string, enum or value types.</remarks>
        public static string GetClientNameForAdminViewElement(this HtmlHelper helper, int pageControlId, string elementName = "Model")
        {
            return string.Format(CultureInfo.InvariantCulture, "{0}_{1}", elementName, pageControlId);
        }
    }
}
